package cn.jobstart.common;

import com.google.zxing.BinaryBitmap;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;
import net.coobird.thumbnailator.Thumbnails;
import sun.font.FontDesignMetrics;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.util.Comparator;
import java.util.HashMap;

/**
 * @author sunke
 * @Date 2020/6/4 22:11
 * @description
 */

public class ImageUtil {


    /**
     * // scale: 缩小的倍数，1代表保持原有的大小(默认1) 范围 1 - 0
     * // outputQuality : 压缩的质量，1代表保持原有的质量(默认1) 范围 1 - 0
     *
     * @param filePath
     * @param scale
     * @param outputQualitySize
     * @throws IOException
     */
    public static void outputQuality(String filePath, float scale, float outputQualitySize) throws IOException {

        Thumbnails.of(filePath).scale(scale).outputQuality(outputQualitySize).toFile(filePath);

    }


    public static void keepAspectRatio(String filePath, int width, int height) throws IOException {

        // BufferedImage backgroundImage = Thumbnails.of("C:\\Users\\Jzdsh\\Desktop\\项目\\ss\\bj.jpg").size(150, 50).asBufferedImage();

        Thumbnails.of(filePath).size(width, height).toFile(filePath);


    }


    public static BufferedImage resize(int targetWidth, int targetHeight,
                                       BufferedImage src) {
        double scaleW = (double) targetWidth / (double) src.getWidth();
        double scaleH = (double) targetHeight / (double) src.getHeight();

        double scale = scaleW < scaleH ? scaleW : scaleH;

        BufferedImage result = new BufferedImage((int) (src.getWidth() * scale),
                (int) (src.getHeight() * scale), BufferedImage.TYPE_INT_ARGB);

        Graphics2D g2d = result.createGraphics();
        g2d.drawImage(src, 0, 0, result.getWidth(), result.getHeight(), null);
        g2d.dispose();

        return result;
    }

    public static String analysisReadQRCode(String path) {
        MultiFormatReader multiFormatReader = new MultiFormatReader();
        HashMap hints = new HashMap();
        hints.put(EncodeHintType.CHARACTER_SET, "GBK");
        try {
            URL url = new URL(path);
            BufferedImage source = ImageIO.read(url);
            BinaryBitmap binaryImg = new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(source)));
            Result result = multiFormatReader.decode(binaryImg, hints);
            return result.getText();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }


    /**
     * 合成图片
     * @param url 二维码内容
     * @param qrcodeW  二维码宽度
     * @param qrcodeH 二维码高度
     * @param backW  背景最大宽
     * @param backH  背景最大高
     * @param backFile  背景图文件
     * @param x  二维码的位置x
     * @param y  二维码的位置y
     * @param saveFile  合成保存的文件
     * @param saveFile  临时存放目录
     */
    public static void compositeByQrCodeUrl(
            String url,int qrcodeW,int qrcodeH,int backW,int backH,String backFile,String saveFile,
            int x,int y,

            String tempDir){

        try {
            String qrCodeFile=tempDir+File.separator+IdGen.uuid()+".jpg";
            QRCodeUtil.encode(url,qrCodeFile,qrcodeW,qrcodeH);

            BufferedImage bi1 = ImageIO.read(new File(backFile));
            BufferedImage bi2 = ImageIO.read(new File(qrCodeFile));
            if (bi2.getHeight() > qrcodeH || bi2.getWidth() > qrcodeW) {
                bi2 = resize(qrcodeW, qrcodeH, bi2);
            }
            if (bi1.getHeight() > backH || bi1.getWidth() > backW) {
                bi1 = resize(backW, backH, bi1);
            }

            Graphics2D g = bi1.createGraphics();

            g.drawImage(bi2, x, y, null);
            g.dispose();

            File outputFile = new File(saveFile);
            //此处要写PNG否则可能会出现遮罩层
            ImageIO.write(bi1, "png", outputFile);

            FileUtil.deleteFile(qrCodeFile);




        } catch (Exception e) {

        }


    }



    /**
     * 合成图片 上导在中间
     *
     * @param upFile
     * @param downFile
     * @param upFileW
     * @param upFileH
     * @param saveFile
     * @param drawFont
     */
    public static void compositeCenterImg(
            String upFile, String downFile
            , int upFileW, int upFileH, String saveFile
            , DrawFont drawFont


    ) {

        try {
            BufferedImage bi1 = ImageIO.read(new File(downFile));
            BufferedImage bi2 = ImageIO.read(new File(upFile));
            if (bi2.getHeight() > upFileH || bi2.getWidth() > upFileW) {
                bi2 = resize(upFileW, upFileH, bi2);
            }
            Graphics2D g = bi1.createGraphics();
            if (StringUtil.isNotObjEmpty(drawFont) && StringUtil.isNotEmpty(drawFont.getContent())) {
                Font font = getDefinedFont(drawFont);

                //消除画图锯齿
                g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                //消除文字锯齿
                g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
                if (font != null) {
                    g.setFont(font);
                }
                g.setColor(ColorTools.String2Color(drawFont.getFontColor()));

                g.drawString(drawFont.getContent(), drawFont.getFontX(), drawFont.getFontY());
            }
            int x = (bi1.getWidth() - bi2.getWidth()) / 2;
            int y = (bi1.getHeight() - bi2.getHeight()) / 2;


            g.drawImage(bi2, x, y, null);
            g.dispose();

            File outputFile = new File(saveFile);
            //此处要写PNG否则可能会出现遮罩层
            ImageIO.write(bi1, "png", outputFile);


        } catch (Exception e) {
            e.printStackTrace();
        }


    }


    /**
     * 合成图片
     *
     * @param upFile     上层图片
     * @param downFile   下层背景图
     * @param upFileW    上层图宽度
     * @param upFileH    上层图高度
     * @param saveFile   合成保存
     * @param upPosition 上传位置 0：左上  1：右上  2：左下，3 右下 4：居中
     * @param drawFont
     */
    public static void compositeImg(
            String upFile, String downFile,
            int upFileW, int upFileH, String saveFile
            , int upPosition
            , DrawFont drawFont


    ) {

        try {
            BufferedImage bi1 = ImageIO.read(new File(downFile));
            BufferedImage bi2 = ImageIO.read(new File(upFile));


            if (bi2.getHeight() > upFileH || bi2.getWidth() > upFileW) {
                bi2 = resize(upFileW, upFileH, bi2);
            }

            Graphics2D g = bi1.createGraphics();
            if (StringUtil.isNotObjEmpty(drawFont) && StringUtil.isNotEmpty(drawFont.getContent())) {
                Font font = getDefinedFont(drawFont);

                //消除画图锯齿
                g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                //消除文字锯齿
                g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
                if (font != null) {
                    g.setFont(font);
                }
                g.setColor(ColorTools.String2Color(drawFont.getFontColor()));

                g.drawString(drawFont.getContent(), drawFont.getFontX(), drawFont.getFontY());
            }


            int x = (bi1.getWidth() - bi2.getWidth()) / 2;
            int y = (bi1.getHeight() - bi2.getHeight()) / 2;
            //左上
            if (upPosition == 0) {
                x = 0;
                y = 0;
            } else if (upPosition == 1) {
                x = bi1.getWidth() - bi2.getWidth();
                y = 0;
            } else if (upPosition == 2) {
                x = 0;
                y = bi1.getHeight() - bi2.getHeight();
            } else if (upPosition == 3) {
                x = bi1.getWidth() - bi2.getWidth();
                y = bi1.getHeight() - bi2.getHeight();
            }


            g.drawImage(bi2, x, y, null);
            g.dispose();

            File outputFile = new File(saveFile);
            //此处要写PNG否则可能会出现遮罩层
            ImageIO.write(bi1, "png", outputFile);


        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    /**
     * 全成图片
     *
     * @param upFile   上层图片
     * @param downFile 下层图片
     * @param x
     * @param y
     * @param upFileW
     * @param upFileH
     * @param saveFile
     */
    public static void compositeImg(
            String upFile, String downFile
            , int x, int y, int upFileW, int upFileH, String saveFile
            , DrawFont drawFont


    ) {

        try {
            BufferedImage bi1 = ImageIO.read(new File(downFile));
            BufferedImage bi2 = ImageIO.read(new File(upFile));
            if (bi2.getHeight() > upFileH || bi2.getWidth() > upFileW) {
                bi2 = resize(upFileW, upFileH, bi2);
            }
            Graphics2D g = bi1.createGraphics();
            if (StringUtil.isNotObjEmpty(drawFont) && StringUtil.isNotEmpty(drawFont.getContent())) {
                Font font = getDefinedFont(drawFont);

                //消除画图锯齿
                g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                //消除文字锯齿
                g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
                if (font != null) {
                    g.setFont(font);
                }
                g.setColor(ColorTools.String2Color(drawFont.getFontColor()));

                g.drawString(drawFont.getContent(), drawFont.getFontX(), drawFont.getFontY());
            }
            g.drawImage(bi2, x, y, null);
            g.dispose();

            File outputFile = new File(saveFile);
            //此处要写PNG否则可能会出现遮罩层
            ImageIO.write(bi1, "png", outputFile);


        } catch (Exception e) {
            e.printStackTrace();
        }


    }

    public static void main(String[] args) {


        try {

            String backFile="/Users/sunke/Desktop/aa/1111.jpg";
            String aa="/Users/sunke/Desktop/aa/11111111.jpg";
            String saveFile="/Users/sunke/Desktop/aa/22222.png";
            String tempDir="/Users/sunke/Desktop/aa/";


            compositeByQrCodeUrl("dddd",102,102,300,450,backFile,saveFile,99,310,tempDir);



         //   keepAspectRatio(aa,300,450);

        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("结束");
    }


    /**
     * 合成图片
     *
     * @param w
     * @param h
     * @param bgColor
     * @param imgList
     * @param textList
     * @param basePath
     * @param fontPath
     * @param targetImgName
     */
    public static void draw(
            int w, int h, String bgColor, java.util.List<CodeImg> imgList, java.util.List<CodeText> textList, String basePath, String fontPath,
            String targetImgName

    ) {

        try {
            BufferedImage bi1 = new BufferedImage(w, h,
                    BufferedImage.TYPE_INT_RGB);
            Graphics2D g = bi1.createGraphics();
            g.setColor(Color.WHITE);//设置笔刷白色
            g.fillRect(0, 0, w, h);//填充整个屏幕

            g.setBackground(ColorTools.String2Color(bgColor));

            if (StringUtil.isNotObjEmpty(imgList)) {
                imgList.stream().sorted(Comparator.comparing(CodeImg::getZ)).forEach(codeImg -> {
                    drawImg(g, basePath, codeImg);
                });

            }

            if (StringUtil.isNotObjEmpty(textList)) {
                textList.stream().sorted(Comparator.comparing(CodeText::getZ)).forEach(codeText -> {
                    drawText(g, basePath, fontPath, codeText);
                });

            }
            g.dispose();


            File outputFile = new File(basePath + File.separator + targetImgName + ".png");
            //此处要写PNG否则可能会出现遮罩层
            ImageIO.write(bi1, "png", outputFile);

        } catch (Exception e) {


        }


    }


    /**
     * 画图片
     *
     * @param g
     * @param basePath
     * @param codeImg
     */
    public static void drawImg(Graphics2D g, String basePath, CodeImg codeImg) {
        if (StringUtil.isObjEmpty(codeImg) || StringUtil.isNullOrEmpty(codeImg.getPath())) {
            return;
        }

        try {
            BufferedImage image = null;
            String path = codeImg.getPath();
            if (path.indexOf("://") > 0) {
                URL url = new URL(path);
                image = ImageIO.read(url);

            } else {
                image = ImageIO.read(new File(basePath + File.separator + path));
            }
            image = resize(codeImg.getW(), codeImg.getH(), image);

            g.drawImage(image, codeImg.getX(), codeImg.getY(), null);
        } catch (Exception e) {

        }


    }


    public static void drawText(Graphics2D g, String basePath, String fontPath, CodeText codeText) {

        if (StringUtil.isObjEmpty(codeText)) {
            return;
        }

        int fontSize = codeText.getSize();
        int bold = codeText.getBold();
        String fontColor = codeText.getColor();
        String text = codeText.getText();
        Font font = ImageUtil.getDefinedFont(basePath, fontPath, fontSize, bold);

        //消除画图锯齿
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        //消除文字锯齿
        g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        if (font != null) {
            g.setFont(font);
        }
        g.setColor(ColorTools.String2Color(fontColor));
        FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font);

        g.drawString(text, codeText.getX(), codeText.getY() + metrics.getAscent());//基线对齐改为顶边对齐

    }

    public static Font getDefinedFont(String basePath, String font, int fontSize, int bold) {
        DrawFont drawFont = new DrawFont();
        drawFont.setBasePath(basePath);
        drawFont.setBold(bold);
        drawFont.setFont(font);
        drawFont.setFontSize(fontSize);

        return getDefinedFont(drawFont);

    }

    public static Font getDefinedFont(DrawFont drawFont) {

        Font definedFont = null;

        InputStream is = null;
        BufferedInputStream bis = null;
        try {
            is = new FileInputStream(new File(drawFont.getBasePath() + File.separator + drawFont.getFont()));
            bis = new BufferedInputStream(is);
            definedFont = Font.createFont(Font.TRUETYPE_FONT, is);
            //设置字体大小，float型
            definedFont = definedFont.deriveFont(drawFont.getFontSize());
            if (drawFont.getBold() == 1) {
                definedFont = definedFont.deriveFont(Font.BOLD);
            }
        } catch (FontFormatException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != bis) {
                    bis.close();
                }
                if (null != is) {
                    is.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return definedFont;

    }

    public static int[] getWidthAndHeight(byte[] bytes) {

        try {
            ByteArrayInputStream in = new ByteArrayInputStream(bytes);    //将b作为输入流；

            BufferedImage sourceImg = ImageIO.read(in);     //将in作为输入流，读取图片存

            int width = sourceImg.getWidth();

            int height = sourceImg.getHeight();
            return new int[]{width, height};
        } catch (Exception e) {
            e.printStackTrace();
        }

        return new int[]{100, 100};


    }


}
